package com.frinder.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * Created on 2016/7/31.
 */
@Component
@Aspect
public class SystemLogAdvisor {

    private static final Logger logger = LoggerFactory.getLogger(SystemLogAdvisor.class);

    @Autowired
    private HttpServletRequest request;

    /**
     * com.kiktech 下所有 controller中类的方法
     */
    @Pointcut("execution(* com.frinder..controller..*.*(..))")
    public void controllerPointCut() {
    }


    @Around("controllerPointCut()")
    public Object handle(ProceedingJoinPoint point) throws Throwable {
        long bTime = System.nanoTime();
        StringBuilder requestStr = new StringBuilder();
        requestStr.append("HttpServletRequest : ")
                .append("Method {{}}, ")
                .append("URL {{}}, ")
                .append("URI {{}}, ")
                .append("PathInfo {{}}, ")
                .append("QueryString {{}}, ")
                .append("RemoteAddr {{}}, ")
                .append("RemoteHost {{}}, ")
                .append("RemotePort {{}}, ")
                .append("LocalAddr {{}}, ")
                .append("LocalName {{}}, ")
                .append("LocalPort {{}}, ");
        logger.debug(requestStr.toString(),
                request.getMethod(),
                request.getRequestURL(),
                request.getRequestURI(),
                request.getPathInfo(),
                request.getQueryString(),
                request.getRemoteAddr(),
                request.getRemoteHost(),
                request.getRemotePort(),
                request.getLocalAddr(),
                request.getLocalName(),
                request.getLocalPort());
        logger.debug("ProceedingJoinPoint {{}}, Args {{}}", point, point.getArgs());
        Object result;
        try {
            result = point.proceed();
        } catch (Throwable throwable) {
            logger.error(throwable.getMessage(), throwable);
            throw new Throwable(throwable);
        }
        logger.info("response info : {}", result);
        long eTime = System.nanoTime();
        logger.info("take time : {} ns !", (eTime - bTime));
        return result;
    }


}
